package jk.fox.spring.scanner;

import jk.fox.spring.bootstrap.SpringRpcContext;
import jk.fox.annotaion.RpcService;
import jk.fox.engine.RpcNodeDefinition;
import org.springframework.beans.factory.config.BeanDefinitionHolder;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.context.annotation.ClassPathBeanDefinitionScanner;
import org.springframework.core.type.filter.AnnotationTypeFilter;

import java.util.Set;

/**
 * Spring-rpc 服务提供者扫描器
 * @author cuichao
 * @Description: RpcClassPathBeanDefinitionScanner
 * @Date: create in 2020/5/28 14:14
 */
public class RpcClassPathBeanDefinitionScanner extends ClassPathBeanDefinitionScanner{

    private SpringRpcContext context;
    private ConfigurableListableBeanFactory beanFactory;

    public RpcClassPathBeanDefinitionScanner(BeanDefinitionRegistry registry, SpringRpcContext context) {
        super(registry,false);
        //注册RpcService拦截器
        addIncludeFilter(new AnnotationTypeFilter(RpcService.class));
        this.context = context;
    }


    @Override
    protected Set<BeanDefinitionHolder> doScan(String... basePackages) {
        Set<BeanDefinitionHolder> beanDefinitionHolders = super.doScan(basePackages);
        for (BeanDefinitionHolder holder : beanDefinitionHolders) {
            String beanClassName = holder.getBeanDefinition().getBeanClassName();
            String beanName = holder.getBeanName();
            try {
                Class<?> target = Class.forName(beanClassName);
                context.registryService(beanName,target,null);
                RpcNodeDefinition rnd = context.getRpcNodeDefinition(target);
                if(beanFactory != null){
                    //注册别名
                    beanFactory.registerAlias(beanName,rnd.getId());
                }
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            }
        }
        return beanDefinitionHolders;
    }



    public void setBeanFactory(ConfigurableListableBeanFactory beanFactory) {
        this.beanFactory = beanFactory;
    }
}
